package com.lonni.rpc.core.socket.server;

import com.alibaba.fastjson2.JSON;
import com.lonni.rpc.core.commom.RpcMsgType;
import com.lonni.rpc.core.model.RpcRequest;
import com.lonni.rpc.core.model.RpcResponse;
import com.lonni.rpc.core.register.ServiceCache;
import com.lonni.rpc.core.register.model.Service;
import com.lonni.rpc.core.socket.codec.RpcProtocol;
import com.lonni.rpc.core.socket.codec.RpcProtocolHeader;
import com.lonni.rpc.core.spring.SpringContext;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

/**
 * 服务端处理 处理rpc请求
 *
 * @author: Lonni
 * @date: 2024/7/9 0009 9:48
 */
@Slf4j
public class RpcServerHanlder extends SimpleChannelInboundHandler<RpcProtocol<RpcRequest>> {

    public RpcServerHanlder() {
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcProtocol<RpcRequest> protocol) throws Exception {

        log.info("RpcNettyServer接受到请求:{}", JSON.toJSONString(protocol));
        RpcRequest request = protocol.getBody();
        //从请求中构建Service对象
        Service service = Service.builder()
                .interfaceName(request.getInterfaceName())
                .version(request.getVersion())
                .group(request.getGroup())
                .build();
        //从缓存中拿到具体的bean
        Object bean = ServiceCache.getBean(service);
        //反射调用
        Method method = ReflectionUtils.findMethod(bean.getClass(), request.getMethodName(), request.getParamTypes());
        RpcResponse response = RpcResponse.builder()
                .data(null)
                .exception(null)
                .build();
        try {
            Object data = ReflectionUtils.invokeMethod(method, bean, request.getParams());
            response.setData(data);
        } catch (Exception exception) {
            log.info("netty rpc 提供者调用发生错误");
            response.setException(exception);
        }
        RpcProtocol<RpcResponse> resProtocol = new RpcProtocol<>();
        RpcProtocolHeader header = protocol.getHeader();
        header.setMsgType((byte) RpcMsgType.RESPONSE.ordinal());
        resProtocol.setBody(response);
        resProtocol.setHeader(header);
        ctx.writeAndFlush(resProtocol);
    }
}



